home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1998 April: Mac OS SDK / Dev.CD Apr 98 SDK1.toast / Development Kits (Disc 1) / QuickDraw 3D / Samples / SampleCode / TriGrids / Sources / TriGridShell.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-08-14  |  18.0 KB  |  703 lines  |  [TEXT/MPS ]

  1. //
  2. // This is box, the QuickDraw 3D starter program.  Written for the
  3. // Getting started with QuickDraw 3D Develop article.  This app does not have 
  4. // graceful error handling - it's purpose is to illustrate a very basic QuickDraw 
  5. // 3D program.
  6. //
  7. // Nick Thompson - January 6th 1994
  8. //
  9. // Modification History:
  10. //
  11. //    1/6/95        nick    initial version based on cube
  12. //    12/31/94    nick    cube modifications for QuickDraw 3d sample code
  13. //    03/22/95    rdd        adapted from BoxShell.c: added simple picking
  14. //                        and trigrid selection via number keys
  15. //    04/12/95    rdd        added SetCameraLocation.
  16. //    04/14/95    rdd     added menu support.
  17. //  
  18.  
  19.  
  20. // system headers
  21. #include <Desk.h>
  22. #include <Dialogs.h>
  23. #include <DiskInit.h>
  24. #include <Fonts.h>
  25. #include <Menus.h>
  26. #include <PictUtil.h>
  27. #include <QDOffScreen.h>
  28. #include <QuickDraw.h>
  29. #include <Resources.h>
  30. #include <SegLoad.h>
  31. #include <StandardFile.h>
  32. #include <TextEdit.h>
  33. #include <ToolUtils.h>
  34.  
  35. // for QuickDraw 3D
  36. #include "QD3D.h"
  37. #include "QD3DMath.h"
  38. #include "QD3DCamera.h"
  39. #include "QD3DDrawContext.h"
  40. #include "QD3DShader.h"
  41. #include "QD3DTransform.h"
  42. #include "QD3DGroup.h"
  43. #include "QD3DPick.h"
  44.  
  45.  
  46. #include "TriGridShell.h"
  47. #include "TriGrid3DSupport.h"
  48. #include "GeometrySample.h"
  49. #include "Textures2.h"
  50.  
  51. //-------------------------------------------------------------------------------------------
  52.  
  53. struct _documentRecord {
  54.     TQ3ViewObject    fView ;                    // the view for the scene
  55.     TQ3GroupObject    fModel ;                // object in the scene being modelled
  56.     TQ3StyleObject    fInterpolation ;        // interpolation style used when rendering
  57.     TQ3StyleObject    fBackFacing ;            // whether to draw shapes that face away from the camera
  58.     TQ3StyleObject    fFillStyle ;            // whether drawn as solid filled object or decomposed to components
  59.     TQ3Matrix4x4    fRotation ;                // the transform for the model
  60.     unsigned short    fGeometryNum ;            // triGrid geometry 1-9 (menu item number)
  61.     unsigned short    fTextureType ;            // method of uv parameterization for texture (menu item number)
  62.     unsigned short    fPictureNum ;            // PICT (menu item number)
  63. };
  64.  
  65. typedef struct _documentRecord DocumentRec, *DocumentPtr, **DocumentHdl ;
  66.  
  67.  
  68. //-------------------------------------------------------------------------------------------
  69. // function prototypes
  70.  
  71. static void         InitToolbox( void ) ;
  72. static Boolean        SetUpMenus (void) ;
  73. static void            IntializeMenuItems (DocumentPtr theDocument) ;
  74. static void         MainEventLoop( void ) ;
  75. static void         HandleKeyPress(EventRecord *pEvent) ;
  76. static void            DoAboutBox (void);
  77. static void            DoMenuCommand (long menuResult) ;
  78. static void         HandleOSEvent(EventRecord *event) ;
  79. static void            InitDocumentData( DocumentPtr theDocument ) ;
  80. static TQ3Status    DocumentDraw3DData( DocumentPtr theDocument ) ;
  81. static void            DisposeDocumentData( DocumentPtr theDocument) ;
  82. static void            SetCameraLocation (TQ3ViewObject view, float x, float y, float z);
  83. static void            ChangeGeometry (DocumentPtr theDocument) ;
  84. static void            DoPicking(EventRecord *event) ;
  85.  
  86.  
  87. //-------------------------------------------------------------------------------------------
  88. //
  89.  
  90. Boolean         gQuitFlag         = false ;
  91. WindowPtr        gMainWindow        = nil ;
  92. DocumentRec        gDocument ;
  93. Handle            ghMenuBar ;
  94. short            gNumPictures ;
  95.  
  96.  
  97. //-------------------------------------------------------------------------------------------
  98. // main()
  99. // entry point for the application, initialize the toolbox, initialize QuickDraw 3D
  100. // and enter the main event loop.  On exit from the main event loop, we want to call
  101. // the QuickDraw 3D exit function to clean up QuickDraw 3d.
  102.  
  103. void main(void)
  104. {
  105.     TQ3Status    myStatus;
  106.  
  107.     InitToolbox() ;
  108.     SetUpMenus () ;
  109.  
  110.     //    Initialize QuickDraw 3D, open a connection to the QuickDraw 3D library
  111.     myStatus = Q3Initialize();
  112.     if ( myStatus == kQ3Failure )
  113.         DebugStr("\pErInitialize returned failure.");            
  114.  
  115.     // set up our globals
  116.     gQuitFlag = false ;
  117.     gMainWindow = GetNewCWindow(kWindowRsrcID, nil, (WindowPtr)-1);
  118.  
  119.     InitDocumentData( &gDocument ) ;
  120.     IntializeMenuItems ( &gDocument ) ;
  121.  
  122.     MainEventLoop();
  123.     
  124.     DisposeDocumentData( &gDocument ) ;
  125.     
  126.     //    Close our connection to the QuickDraw 3D library
  127.     myStatus = Q3Exit();
  128.     if ( myStatus == kQ3Failure )
  129.         DebugStr("\pErExit returned failure.");
  130.     
  131. }
  132.  
  133. //-------------------------------------------------------------------------------------------
  134. //
  135.  
  136. void InitDocumentData( DocumentPtr theDocument ) 
  137. {
  138.     // sets up the 3d data for the scene
  139.     // Create view for QuickDraw 3D.
  140.     theDocument->fView = MyNewView( (WindowPtr)gMainWindow ) ;
  141.  
  142.     // the drawing styles:
  143.     theDocument->fInterpolation = Q3InterpolationStyle_New(kQ3InterpolationStyleNone) ;
  144.     theDocument->fBackFacing = Q3BackfacingStyle_New(kQ3BackfacingStyleBoth ) ;
  145.     theDocument->fFillStyle = Q3FillStyle_New(kQ3FillStyleFilled ) ;
  146.  
  147.     // set the rotation matrix the identity matrix
  148.     Q3Matrix4x4_SetIdentity(&theDocument->fRotation);        
  149.  
  150.     theDocument->fGeometryNum = iFlat ;
  151.     theDocument->fTextureType = iNoTexture ;
  152.     theDocument->fPictureNum  = iPictureFirst ;
  153.  
  154.     // the main display group:
  155.     theDocument->fModel = MyNewModel() ;
  156.     ChangeGeometry (theDocument);
  157. }
  158.  
  159. void DisposeDocumentData( DocumentPtr theDocument)
  160. {
  161.  
  162.     if(theDocument->fView)
  163.         Q3Object_Dispose(theDocument->fView) ;                // the view for the scene
  164.  
  165.     if(theDocument->fModel)
  166.         Q3Object_Dispose(theDocument->fModel) ;                // object in the scene being modelled
  167.  
  168.     if(theDocument->fInterpolation)
  169.         Q3Object_Dispose(theDocument->fInterpolation) ;        // interpolation style used when rendering
  170.  
  171.     if(theDocument->fBackFacing)
  172.         Q3Object_Dispose(theDocument->fBackFacing) ;        // whether to draw shapes that face away from the camera
  173.  
  174.     if(theDocument->fFillStyle)
  175.         Q3Object_Dispose(theDocument->fFillStyle) ;            // whether drawn as solid filled object or decomposed to components
  176.  
  177. }
  178. //-----------------------------------------------------------------------------
  179. // 
  180.  
  181. TQ3Status DocumentDraw3DData( DocumentPtr theDocument )
  182. {    
  183.     Q3View_StartRendering(theDocument->fView );
  184.     do {
  185.         Q3Style_Submit( theDocument->fInterpolation, theDocument->fView );
  186.         Q3Style_Submit( theDocument->fBackFacing, theDocument->fView );
  187.         Q3Style_Submit( theDocument->fFillStyle, theDocument->fView );
  188.         Q3MatrixTransform_Submit( &theDocument->fRotation, theDocument->fView );
  189.         Q3DisplayGroup_Submit( theDocument->fModel, theDocument->fView );
  190.     } while (Q3View_EndRendering(theDocument->fView) == kQ3ViewStatusRetraverse );
  191.     return kQ3Success ;
  192. }
  193.  
  194.  
  195. //----------------------------------------------------------------------------------
  196. //
  197. void InitToolbox()
  198. {
  199.     Handle        menuBar = nil;
  200.  
  201.     MaxApplZone() ;
  202.     MoreMasters() ; MoreMasters() ; MoreMasters() ; 
  203.     
  204.     InitGraf( &qd.thePort );
  205.     InitFonts();
  206.     InitWindows();
  207.     InitCursor();
  208.  
  209.     FlushEvents( everyEvent, 0 ) ;
  210.     // initialize application globals
  211.     
  212.     gQuitFlag = false;
  213.     
  214. }
  215.  
  216.  
  217. //-------------------------------------------------------------------------------------------
  218. //
  219. Boolean SetUpMenus (void)
  220. {
  221.     Boolean        goodMenus;
  222.  
  223.     goodMenus = true;
  224.  
  225.     ghMenuBar = GetNewMBar (kMenuBarRsrc);
  226.     if (ghMenuBar != nil)
  227.     {
  228.         SetMenuBar (ghMenuBar);
  229.         AppendResMenu (GetMenuHandle (mApple), (ResType) 'DRVR');
  230.         DrawMenuBar ();
  231.     }
  232.     else
  233.     {
  234.         DebugStr ("\pSetUpMenus: Couldn't find menu bar.");
  235.         ghMenuBar = nil;
  236.         goodMenus = false;
  237.     }
  238.  
  239.      return (goodMenus);
  240. }
  241.  
  242.  
  243. //-------------------------------------------------------------------------------------------
  244. //
  245. void IntializeMenuItems (DocumentPtr theDocument)
  246. {
  247.     MenuHandle    hMenu;
  248.     Str255        menuPrefix = {"\pPicture "},
  249.                 itemText,
  250.                 numString;
  251.     long        item;
  252.     short        rsrcID;
  253.     ResType        rsrcType;
  254.     Handle        hPict;
  255.  
  256.     hMenu = GetMenuHandle(mTexture);
  257.  
  258.     gNumPictures = Count1Resources ('PICT');
  259.  
  260.     /* PICT resources to be used as textures must be numbered starting with kFirstPICTRsrcID */
  261.     SetResLoad (false);
  262.     for (item = 0; item < gNumPictures; item++)
  263.     {
  264.         itemText[0] = 0;
  265.  
  266.         hPict = GetResource ('PICT', kFirstPICTRsrcID + item);
  267.         if (hPict != NULL)
  268.             GetResInfo (hPict, &rsrcID, &rsrcType, itemText);
  269.         else
  270.             break;
  271.  
  272.         if (itemText[0] == 0)
  273.         {
  274.             BlockMove ((Ptr) menuPrefix, (Ptr) itemText, (Size) menuPrefix[0]+1);
  275.             NumToString (item+1, numString);
  276.             itemText[0] += numString[0];
  277.             BlockMove ((Ptr) &numString[1], (Ptr) itemText[itemText[0]+1], (Size) numString[0]);
  278.         }
  279.  
  280.         AppendMenu (hMenu, itemText);
  281.     }
  282.     SetResLoad (true);
  283.  
  284.     gNumPictures = item;
  285.  
  286.     if (theDocument->fTextureType == iNoTexture)
  287.     {
  288.         for (item = iPictureFirst; item < iPictureFirst + gNumPictures; item++)
  289.             DisableItem(hMenu, item);
  290.     }
  291.  
  292.  
  293.     CheckItem (GetMenuHandle (mGeometry), theDocument->fGeometryNum, true);
  294.     CheckItem (hMenu, theDocument->fTextureType, true);
  295.     CheckItem (hMenu, theDocument->fPictureNum,  true);
  296. }
  297.  
  298.  
  299. //-------------------------------------------------------------------------------------------
  300. //
  301. void MainEventLoop()
  302. {
  303.     EventRecord     event;
  304.     WindowPtr       window;
  305.     short           thePart;
  306.     Rect            screenRect, updateRect;
  307.     Point            aPoint = {100, 100};
  308.     
  309.  
  310.     while( !gQuitFlag )
  311.     {
  312.         if (WaitNextEvent( everyEvent, &event, 0, nil ))
  313.         {
  314.  
  315.             switch (event.what) {
  316.                 case mouseDown:
  317.                 
  318.                     thePart = FindWindow( event.where, &window );
  319.                     
  320.                     switch( thePart ) {
  321.                         case inMenuBar: 
  322.                             DoMenuCommand (MenuSelect (event.where));
  323.                             break;
  324.  
  325.                         case inSysWindow:
  326.                             SystemClick (&event, window);
  327.                             break;
  328.  
  329.                         case inDrag:
  330.                             screenRect = (**GetGrayRgn()).rgnBBox;
  331.                             DragWindow( window, event.where, &screenRect );
  332.                             break ;
  333.                     
  334.                         case inContent:
  335.                             if (window != FrontWindow())
  336.                                 SelectWindow( window );
  337.                                 DoPicking(&event);
  338.                             break ;
  339.                     
  340.                         case inGoAway:
  341.                             if (TrackGoAway( window, event.where )) {
  342.                                 DisposeWindow ( window );
  343.                                 gQuitFlag = true;
  344.                             }
  345.                             break ;
  346.                             
  347.                         default:
  348.                         case inGrow:
  349.                         case inZoomIn:
  350.                         case inZoomOut:
  351.                             break ;
  352.                     }
  353.                     break ;
  354.                             
  355.                         
  356.                 case updateEvt:
  357.                     window = (WindowPtr)event.message;
  358.                     updateRect = (**(window->visRgn)).rgnBBox;
  359.                     SetPort( window ) ;
  360.                     BeginUpdate( window );
  361.                     DocumentDraw3DData( &gDocument ) ;
  362.                     EndUpdate( window );
  363.                     break ;
  364.                     
  365.                 case keyDown:
  366.                 case autoKey:
  367.                     HandleKeyPress(&event);
  368.                     break;
  369.                     
  370.                 case diskEvt:
  371.                     if ( HiWord(event.message) != noErr ) 
  372.                         (void) DIBadMount(aPoint, event.message);
  373.                     break;
  374.                     
  375.                 case osEvt:
  376.                 case activateEvt:
  377.                     break;
  378.  
  379.  
  380.             }
  381.         }
  382.         else {
  383.             // we received a null event, rotate the cube
  384.             TQ3Matrix4x4    tmp;
  385.             Rect            theRect = ((GrafPtr)gMainWindow)->portRect ;
  386.             
  387.             SetPort((GrafPtr)gMainWindow) ;
  388.             Q3Matrix4x4_SetRotate_XYZ(&tmp, 0.1, 0.12, 0.08);
  389.             Q3Matrix4x4_Multiply(&gDocument.fRotation, &tmp, &gDocument.fRotation);
  390.  
  391.             InvalRect( &theRect ) ;
  392.         }
  393.     }
  394. }
  395.  
  396.  
  397. //-------------------------------------------------------------------------------------------
  398. //
  399. void HandleKeyPress(EventRecord *pEvent)
  400. {
  401.     char            charCode;
  402.  
  403.     charCode = pEvent->message & charCodeMask;
  404.  
  405.     if (pEvent->modifiers & btnState)
  406.     {
  407.         /* Button is UP with a key */
  408.         if (pEvent->modifiers & cmdKey)
  409.         {
  410.             DoMenuCommand (MenuKey (charCode));
  411.         }
  412.     }
  413.     else
  414.     {
  415.         /* Button is DOWN with a key */
  416.     }
  417. }
  418.  
  419.  
  420. //-------------------------------------------------------------------------------------------
  421. //
  422. void DoAboutBox (void)
  423. {
  424.     DialogPtr    theDialog;
  425.     short        itemHit;
  426.  
  427.     theDialog = GetNewDialog(kDialogRsrcID, nil, (WindowPtr)-1);
  428.     if (theDialog == nil)
  429.         return;
  430.         
  431.     do
  432.     {
  433.         ModalDialog (nil, &itemHit);
  434.     }
  435.     while (itemHit != ok);
  436.  
  437.     DisposeDialog (theDialog);
  438. }
  439.  
  440.  
  441. //-------------------------------------------------------------------------------------------
  442. //
  443. void DoMenuCommand (long menuResult)
  444. {
  445.     short        menuID,
  446.                 itemNumber;
  447.  
  448.     if (! menuResult)
  449.         return;
  450.  
  451.     menuID       = HiWord (menuResult);
  452.     itemNumber = LoWord (menuResult);
  453.  
  454.     switch (menuID)
  455.     {
  456.         case mApple:
  457.             switch (itemNumber)
  458.             {
  459.             case iAbout:
  460.                 DoAboutBox();
  461.             break;
  462.  
  463.             default:
  464.                 {
  465.                     MenuHandle    hMenu;
  466.                     Str255        deskAccName;
  467.                     GrafPtr        oldPort;
  468.  
  469.                     hMenu = GetMenuHandle (menuID);
  470.                     if (hMenu != nil)
  471.                     {
  472.                         GetPort (&oldPort);
  473.  
  474.                         GetMenuItemText (hMenu, itemNumber, deskAccName);
  475.                         (void) OpenDeskAcc (deskAccName);
  476.                         SetPort (oldPort);
  477.                     }
  478.                 }
  479.                 break;
  480.             }
  481.             break;
  482.  
  483.         case mFile:
  484.             switch (itemNumber)
  485.             {
  486.             case iNew:            break;
  487.             case iOpen:            break;
  488.             case iClose:        break;
  489.  
  490.             case iQuit:
  491.                 gQuitFlag = true;break;
  492.  
  493.             default: SysBeep(1);break;
  494.             }
  495.             break;
  496.  
  497.         case mEdit:
  498.             if (! SystemEdit (itemNumber - 1))
  499.                 switch (itemNumber)
  500.                 {
  501.                 case iUndo:        break;
  502.                 case iCut:        break;
  503.                 case iCopy:        break;
  504.                 case iPaste:    break;
  505.                 case iClear:    break;
  506.                 }
  507.             break;
  508.  
  509.         case mGeometry:
  510.             if (itemNumber != gDocument.fGeometryNum)
  511.             {
  512.                 CheckItem (GetMenuHandle (mGeometry), gDocument.fGeometryNum, false);
  513.                 gDocument.fGeometryNum = itemNumber;
  514.                 CheckItem (GetMenuHandle (mGeometry), gDocument.fGeometryNum, true);
  515.                 ChangeGeometry (&gDocument);
  516.             }
  517.             break;
  518.  
  519.         case mTexture:
  520.             if (itemNumber >= iNoTexture  &&  itemNumber <= iFaceTexture)
  521.             {
  522.                 if (itemNumber != gDocument.fTextureType)
  523.                 {
  524.                     long    item;
  525.  
  526.                     if (gDocument.fTextureType == iNoTexture)
  527.                     {
  528.                         for (item = iPictureFirst; item < iPictureFirst + gNumPictures; item++)
  529.                             EnableItem(GetMenuHandle (menuID), item);
  530.                     }
  531.                     else
  532.                     if (itemNumber == iNoTexture)
  533.                     {
  534.                         for (item = iPictureFirst; item < iPictureFirst + gNumPictures; item++)
  535.                             DisableItem(GetMenuHandle (menuID), item);
  536.                     }
  537.  
  538.                     CheckItem (GetMenuHandle (mTexture), gDocument.fTextureType, false);
  539.                     gDocument.fTextureType = itemNumber;
  540.                     CheckItem (GetMenuHandle (mTexture), gDocument.fTextureType, true);
  541.                     ChangeGeometry (&gDocument);
  542.                 }
  543.             }
  544.             else
  545.             if (itemNumber >= iPictureFirst  && itemNumber <= iPictureFirst + gNumPictures - 1)
  546.             {
  547.                 if (itemNumber != gDocument.fPictureNum)
  548.                 {
  549.                     CheckItem (GetMenuHandle (mTexture), gDocument.fPictureNum, false);
  550.                     gDocument.fPictureNum = itemNumber;
  551.                     CheckItem (GetMenuHandle (mTexture), gDocument.fPictureNum, true);
  552.                     ChangeGeometry (&gDocument);
  553.                 }
  554.             }
  555.             break;
  556.  
  557.         default:
  558.             break;
  559.  
  560.     }  /*  switch (menuID)  */
  561.  
  562.     HiliteMenu (0);
  563. }
  564.  
  565.  
  566. //-------------------------------------------------------------------------------------------
  567. //
  568. void SetCameraLocation (TQ3ViewObject view, float x, float y, float z)
  569. {
  570.     TQ3CameraObject    camera;
  571.     TQ3CameraData    cameraData;
  572.  
  573.     Q3View_GetCamera(view, &camera);
  574.     if (camera != nil)
  575.     {
  576.         Q3Camera_GetData(camera, &cameraData);
  577.         Q3Point3D_Set(&cameraData.placement.cameraLocation, x, y, z);
  578.         Q3Camera_SetData(camera, &cameraData);
  579.         Q3Object_Dispose(camera);
  580.     }
  581. }
  582.  
  583.  
  584. //-------------------------------------------------------------------------------------------
  585. //
  586. void ChangeGeometry (DocumentPtr theDocument)
  587. {
  588.     TQ3Status            status;
  589.     TQ3Object            object;
  590.     TQ3GroupPosition    position;
  591.     unsigned long        triGridLibNum;
  592.  
  593.     if (theDocument->fModel == nil)
  594.         return;
  595.  
  596.     status = Q3Group_GetFirstPositionOfType(theDocument->fModel, kQ3ShapeTypeGeometry, &position);
  597.     if (status == kQ3Success  &&  position != nil)
  598.     {
  599.         object = Q3Group_RemovePosition(theDocument->fModel, position);
  600.         Q3Object_Dispose(object);
  601.         object = NULL;
  602.     }
  603.  
  604.     switch (theDocument->fTextureType)
  605.     {
  606.         case iNoTexture:        triGridLibNum = (theDocument->fGeometryNum-1) + kGeometryLibraryRange_Simple;            break;
  607.         case iGeometryTexture:    triGridLibNum = (theDocument->fGeometryNum-1) + kGeometryLibraryRange_UVGeoAttributes;    break;
  608.         case iFaceTexture:        triGridLibNum = (theDocument->fGeometryNum-1) + kGeometryLibraryRange_UVFaceAttributes;break;
  609.     }
  610.     object = NewLibraryTriGrid(triGridLibNum);
  611.     if (object == NULL)
  612.         return;
  613.     Q3Group_AddObject (theDocument->fModel, object);
  614.  
  615.     /* Add diffuse color if no texture */
  616.     if (theDocument->fTextureType == iNoTexture)
  617.     {
  618.         TQ3AttributeSet        attrSet;
  619.         TQ3ColorRGB            rgbColor;
  620.  
  621.         attrSet = Q3AttributeSet_New();
  622.         if (attrSet != NULL)
  623.         {
  624.             Q3ColorRGB_Set(&rgbColor, 0.0, 0.75, 0.75);
  625.             status = Q3AttributeSet_Add(attrSet, kQ3AttributeTypeDiffuseColor, &rgbColor);
  626.             if (status == kQ3Success)
  627.             {
  628.                 Q3Geometry_SetAttributeSet(object, attrSet);
  629.                 Q3Object_Dispose(attrSet);
  630.             }
  631.         }
  632.     }
  633.     else
  634.         /* Add texture shader */
  635.         AddResourceTextureToGroup(theDocument->fPictureNum - iPictureFirst + kFirstPICTRsrcID, theDocument->fModel);
  636.  
  637.     Q3Object_Dispose(object);
  638.  
  639.     /* (These cameral locations could be calculated) */
  640.     switch (theDocument->fGeometryNum)
  641.     {
  642.     case iFlat:            SetCameraLocation (theDocument->fView, 0.0, 0.0,  4.0);    break;
  643.     case iTorus:        SetCameraLocation (theDocument->fView, 0.0, 0.0, 10.0);    break;
  644.     case iWaveyTorus:    SetCameraLocation (theDocument->fView, 0.0, 0.0, 10.0);    break;
  645.     case iSplash:        SetCameraLocation (theDocument->fView, 0.0, 0.0, 25.0);    break;
  646.     case iSphere:        SetCameraLocation (theDocument->fView, 0.0, 0.0,  7.0);    break;
  647.     case iCone:            SetCameraLocation (theDocument->fView, 0.0, 0.0,  9.0);    break;
  648.     case iPipe:            SetCameraLocation (theDocument->fView, 0.0, 0.0, 10.0);    break;
  649.     case iSteps:        SetCameraLocation (theDocument->fView, 0.0, 0.0, 30.0);    break;
  650.     case iSpring:        SetCameraLocation (theDocument->fView, 0.0, 0.0, 11.0);    break;
  651.     }
  652. }
  653.  
  654.  
  655. //-------------------------------------------------------------------------------------------
  656. //
  657. void DoPicking(EventRecord *event)
  658. {
  659.     Point                    screenPoint;
  660.     TQ3WindowPointPickData    withData;
  661.     unsigned long            numPicked;
  662.     TQ3PickObject            pickObject;
  663.     TQ3Status                status;
  664.     TQ3ViewStatus            viewStatus;
  665.     
  666.     withData.data.sort             =    kQ3PickSortNone;
  667.     withData.data.numHitsToReturn=    kQ3ReturnAllHits;
  668.     withData.data.mask             =    kQ3PickDetailMaskObject;
  669.                                   
  670.     screenPoint = event->where;
  671.     GlobalToLocal (&screenPoint);
  672.     withData.point.x = screenPoint.h;
  673.     withData.point.y = screenPoint.v;
  674.  
  675.     withData.vertexTolerance = withData.edgeTolerance = 2.0;
  676.  
  677.     pickObject = Q3WindowPointPick_New(&withData);
  678.  
  679.     status = Q3View_StartPicking(gDocument.fView, pickObject);
  680.     if (status == kQ3Failure)
  681.         debugstr ("DoPicking: Q3View_StartPicking failed.");
  682.     do {
  683.         status = Q3DisplayGroup_Submit(gDocument.fModel, gDocument.fView);
  684.         if (status == kQ3Failure)
  685.             debugstr ("DoPicking: Q3View_StartPicking failed.");
  686.  
  687.         viewStatus = Q3View_EndPicking(gDocument.fView);
  688.     } while (viewStatus == kQ3ViewStatusRetraverse);
  689.  
  690.     if (viewStatus != kQ3ViewStatusDone)
  691.         debugstr ("DoPicking: Q3View_EndPicking failed.");
  692.  
  693.  
  694.     if (Q3Pick_GetNumHits(pickObject, &numPicked) && (numPicked != 0)) {
  695.         SetCursor(*GetCursor(plusCursor));
  696.         SysBeep(1);
  697.     } else {
  698.         SetCursor(&qd.arrow);
  699.     }
  700.  
  701.     Q3Object_Dispose(pickObject);
  702. }
  703.